package com.ciei.dpagm.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.ciei.dpagm.common.enums.*;
import com.ciei.dpagm.common.service.BaseService;
import com.ciei.dpagm.entity.*;
import com.ciei.dpagm.mapper.ChipMapper;
import com.ciei.dpagm.service.conditionRule.ConditionHandleService;
import com.ciei.dpagm.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author wangyan
 * @date 2023/05/08
 */
@Service
public class ChipService extends BaseService<ChipMapper, Chip> {

    @Value("${baseFilePath}")
    private String baseFilePath;

    @Autowired
    private CircuitGenerationModuleChipService circuitGenerationModuleChipService;

    @Autowired
    private ChipClockParameterService chipClockParameterService;

    @Autowired
    private ChipPinService chipPinService;

    @Autowired
    private ChipPinFunctionService chipPinFunctionService;

    @Autowired
    private ChipPinParameterService chipPinParameterService;

    @Autowired
    private ChipInterfaceService chipInterfaceService;

    @Autowired
    private ChipInterfacePinFunctionService chipInterfacePinFunctionService;

    @Autowired
    private ChipInterfacePinFunctionParameterService chipInterfacePinFunctionParameterService;

    @Autowired
    private ChipInterfaceParameterService chipInterfaceParameterService;

    @Autowired
    private FilesService filesService;

    @Lazy
    @Autowired
    private DriverLibraryService driverLibraryService;

    @Autowired
    private RuleSetService ruleSetService;

    @Autowired
    private RuleService ruleService;

    @Autowired
    private ConditionService conditionService;

    @Autowired
    private ConditionHandleService conditionHandleService;



    /**
     * 通过文件增加芯片
     * @param data
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject addChipByFile(JSONObject data, Users currentUser){
        Integer chipType = data.getInteger("chipType");
        JSONObject chipData = parseJsonFile(data,chipType);
        if (chipData == null){
            return JsonUtil.getFail(ErrorCodeEnum.IMPORT_CONTENT_ERROR);
        }
        Chip chip = chipData.toJavaObject(Chip.class);
        if (StringUtils.isBlank(chip.getModel()) || StringUtils.isBlank(chip.getDisplayName())|| StringUtils.isBlank(chip.getManufacturer())
                || StringUtils.isBlank(chip.getDisplayCategory())|| StringUtils.isBlank(chip.getCategory())){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"缺少芯片基本信息!");
        }
        if (isDuplicateModelBySameManufacturer(chip.getManufacturer(),chip.getModel(),null)){
            return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"相同厂商下,芯片型号已存在!");
        }
        Integer userId = currentUser.getUserId();
        chip.setCreatorId(userId);
        chip.setType(chipType);
        //保存芯片信息
        save(chip);
        if (ChipTypeEnum.MASTER.getType().equals(chipType)){
            saveMasterChipInfo(chipData,chip,currentUser);
        }
        filesService.saveFiles(data.getJSONArray("chipDefinitionFiles"),userId,FileRelationTypeEnum.CHIP_DEFINITION.getRelationTypeId(),chip.getChipId());
        addChipFiles(data,chip.getChipId(),chipType,userId);
        if (ChipTypeEnum.MASTER.getType().equals(chipType)) {
            List<RuleSet> ruleSetList = ruleSetService.findByProperty(RuleSet::getChipId, chip.getChipId());
            return ruleSetService.getParameterConfigurationRuleSetList(ruleSetList);
        }
        return JsonUtil.getSuccess("");
    }

    /**
     * 通过文件修改芯片信息
     * @param data
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject updateChipByFile(JSONObject data, Users currentUser){
        Integer chipId = data.getInteger("chipId");
        Chip oldChip = findById(chipId);
        if (oldChip == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的芯片数据!");
        }
        Integer chipType = oldChip.getType();
        JSONObject chipData = parseJsonFile(data,chipType);
        if (chipData == null){
            return JsonUtil.getFail(ErrorCodeEnum.IMPORT_CONTENT_ERROR);
        }
        Chip newChip = chipData.toJavaObject(Chip.class);
        if (StringUtils.isBlank(newChip.getModel()) || StringUtils.isBlank(newChip.getDisplayName())|| StringUtils.isBlank(newChip.getManufacturer())
                || StringUtils.isBlank(newChip.getDisplayCategory())|| StringUtils.isBlank(newChip.getCategory())){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM,"缺少芯片基本信息!");
        }
        if (isDuplicateModelBySameManufacturer(newChip.getManufacturer(),newChip.getModel(),chipId)){
            return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"相同厂商下,芯片型号已存在!");
        }
        Integer userId = currentUser.getUserId();
        newChip.setUpdateUserId(userId);
        newChip.setChipId(chipId);
        //修改芯片基本信息
        updateById(newChip);
        if (ChipTypeEnum.MASTER.getType().equals(chipType)){
            //清空芯片旧数据
            deleteMasterChipInfo(chipId);
            //保存芯片新数据
            saveMasterChipInfo(chipData,newChip,currentUser);
        }
        //修改芯片定义文件
        filesService.updateFiles(data.getJSONArray("chipDefinitionFiles"),userId,FileRelationTypeEnum.CHIP_DEFINITION.getRelationTypeId(),chipId);
        if (ChipTypeEnum.MASTER.getType().equals(chipType)) {
            List<RuleSet> ruleSetList = ruleSetService.findByProperty(RuleSet::getChipId, chipId);
            return ruleSetService.getParameterConfigurationRuleSetList(ruleSetList);
        }
        return JsonUtil.getSuccess("");
    }

    /**
     * 解析json文件
     * @param data
     * @return
     */
    public JSONObject parseJsonFile(JSONObject data,Integer chipType){
        JSONArray chipDefinitionFiles = data.getJSONArray("chipDefinitionFiles");
        String jsonStr = null;
        if (chipDefinitionFiles != null && !chipDefinitionFiles.isEmpty()){
            String filePath = baseFilePath + chipDefinitionFiles.getJSONObject(0).getString("path").replaceFirst("uploads/", "");
            jsonStr = FileUtils.getStr(filePath);
        }
        return validateChipData(jsonStr,chipType);
    }

    /**
     * 保存芯片文件
     * @param data
     * @param chipId
     * @param chipType
     * @param userId
     */
    public void addChipFiles(JSONObject data,Integer chipId,Integer chipType,Integer userId){
        if (ChipTypeEnum.MASTER.getType().equals(chipType)){
            filesService.saveFiles(data.getJSONArray("clockParameterFiles"),userId,FileRelationTypeEnum.CHIP_CLOCK_PARAMETER.getRelationTypeId(),chipId);
        }
        if (ChipTypeEnum.SLAVE.getType().equals(chipType)){
            filesService.saveFiles(data.getJSONArray("performanceParameterFiles"),userId,FileRelationTypeEnum.CHIP_PERFORMANCE_PARAMETER.getRelationTypeId(),chipId);
        }
        filesService.saveFiles(data.getJSONArray("pinFiles"),userId,FileRelationTypeEnum.CHIP_PIN.getRelationTypeId(),chipId);
    }

    /**
     * 修改芯片文件
     * @param data
     * @param chipId
     * @param chipType
     * @param userId
     */
    public void updateChipFiles(JSONObject data,Integer chipId,Integer chipType,Integer userId){
        if (ChipTypeEnum.MASTER.getType().equals(chipType)){
            filesService.updateFiles(data.getJSONArray("clockParameterFiles"),userId,FileRelationTypeEnum.CHIP_CLOCK_PARAMETER.getRelationTypeId(),chipId);
        }
        if (ChipTypeEnum.SLAVE.getType().equals(chipType)){
            filesService.updateFiles(data.getJSONArray("performanceParameterFiles"),userId,FileRelationTypeEnum.CHIP_PERFORMANCE_PARAMETER.getRelationTypeId(),chipId);
        }
        filesService.updateFiles(data.getJSONArray("pinFiles"),userId,FileRelationTypeEnum.CHIP_PIN.getRelationTypeId(),chipId);
    }

    /**
     * 删除芯片文件
     * @param chipId
     * @param chipType
     */
    public void deleteFiles(Integer chipId,Integer chipType){
        if (ChipTypeEnum.MASTER.getType().equals(chipType)){
            filesService.deleteFiles(Arrays.asList(FileRelationTypeEnum.CHIP_DEFINITION.getRelationTypeId(),FileRelationTypeEnum.CHIP_CLOCK_PARAMETER.getRelationTypeId(),FileRelationTypeEnum.CHIP_PIN.getRelationTypeId()),chipId);
        }
        if (ChipTypeEnum.SLAVE.getType().equals(chipType)){
            filesService.deleteFiles(Arrays.asList(FileRelationTypeEnum.CHIP_DEFINITION.getRelationTypeId(),FileRelationTypeEnum.CHIP_PERFORMANCE_PARAMETER.getRelationTypeId(),FileRelationTypeEnum.CHIP_PIN.getRelationTypeId()),chipId);
        }
    }

    /**
     * 保存主控芯片详细信息
     * @param chipData
     * @param chip
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject saveMasterChipInfo(JSONObject chipData,Chip chip,Users currentUser) {
        Integer chipId = chip.getChipId();
        JSONObject clocks = chipData.getJSONObject("clocks");
        RuleSet clockRuleSet = ruleSetService.createParameterConfigurationRuleSet(currentUser.getUserId(),"时钟配置",chip.getChipId());
        clockRuleSet.setType(RuleSetTypeEnum.CLOCK_CONFIGURATION);
        RuleSet pinRuleSet = ruleSetService.createParameterConfigurationRuleSet(currentUser.getUserId(),"引脚配置",chip.getChipId());
        pinRuleSet.setType(RuleSetTypeEnum.PIN_CONFIGURATION);
        RuleSet interfaceResourceRuleSet = ruleSetService.createParameterConfigurationRuleSet(currentUser.getUserId(),"接口资源配置",chip.getChipId());
        interfaceResourceRuleSet.setType(RuleSetTypeEnum.INTERFACE_RESOURCE_CONFIGURATION);
        List<RuleSet> ruleSetList = new ArrayList<>();
        ruleSetList.add(clockRuleSet);
        ruleSetList.add(pinRuleSet);
        ruleSetList.add(interfaceResourceRuleSet);
        ruleSetService.insertBatchSomeColumn(ruleSetList);
        Pattern relationalOperatorPattern = conditionService.getRelationalOperatorPattern();
        Map<Rule,List<Condition>> ruleToConditionListData = new HashMap<>();
        Map<Rule,Rule> dependenciesRuleToConfigurationRuleData = new HashMap<>();
        List<Rule> addRuleList = new ArrayList<>();
        List<Condition> addConditionList = new ArrayList<>();
        List<String> parameterConfigurationDataTypeList = ParameterConfigurationDataTypeEnum.getTypeList();
        if (clocks != null) {
            JSONArray clockParameters = clocks.getJSONArray("parameters");
            if (clockParameters != null && !clockParameters.isEmpty()) {
                List<ChipClockParameter> clockParameterList = new ArrayList<>();
                for (int i = 0; i < clockParameters.size(); i++) {
                    JSONObject clockParameter = clockParameters.getJSONObject(i);
                    ChipClockParameter chipClockParameter = clockParameter.toJavaObject(ChipClockParameter.class);
                    chipClockParameter.setChipId(chipId);
                    clockParameterList.add(chipClockParameter);
                    List<Rule> ruleList = new ArrayList<>();
                    String parameterName = chipClockParameter.getParameterName() == null ? "" : chipClockParameter.getParameterName();
                    String symbol = chipClockParameter.getSymbol() == null ? "" : chipClockParameter.getSymbol();
                    Rule dependenciesRule = ruleService.createDependenciesRule(currentUser.getUserId(), relationalOperatorPattern, ruleToConditionListData, addConditionList, chipClockParameter.getDependencies(), parameterName, clockRuleSet,null,symbol);
                    Rule configurationRule = ruleService.createConfigurationRule(currentUser.getUserId(), addConditionList, parameterConfigurationDataTypeList, ruleToConditionListData, chipClockParameter.getDataType(), chipClockParameter.getValidValues(), parameterName, clockRuleSet,null,symbol);
                    if(dependenciesRule != null){
                        ruleList.add(dependenciesRule);
                        if(configurationRule != null){
                            dependenciesRuleToConfigurationRuleData.put(dependenciesRule,configurationRule);
                        }
                    }
                    if(configurationRule != null){
                        ruleList.add(configurationRule);
                    }
                    addRuleList.addAll(ruleList);
                }
                if (!clockParameterList.isEmpty()) {
                    //保存芯片时钟参数
                    chipClockParameterService.saveBatch(clockParameterList);
                }
            }
            JSONArray pins = chipData.getJSONArray("pins");
            if (pins != null && !pins.isEmpty()) {
                for (int i = 0; i < pins.size(); i++) {
                    JSONObject pin = pins.getJSONObject(i);
                    ChipPin chipPin = pin.toJavaObject(ChipPin.class);
                    chipPin.setChipId(chipId);
                    //保存芯片引脚信息
                    chipPinService.save(chipPin);

                    JSONArray pinNames = pin.getJSONArray("pin_names");
                    if (pinNames != null && !pinNames.isEmpty()) {
                        List<ChipPinFunction> pinFunctionList = new ArrayList<>();
                        for (int j = 0; j < pinNames.size(); j++) {
                            String pinName = pinNames.getString(j);
                            ChipPinFunction pinFunction = new ChipPinFunction();
                            pinFunction.setPinId(chipPin.getPinId());
                            pinFunction.setChipId(chipId);
                            pinFunction.setPinName(pinName);
                            pinFunctionList.add(pinFunction);
                        }
                        if (!pinFunctionList.isEmpty()) {
                            //保存芯片引脚功能信息
                            chipPinFunctionService.saveBatch(pinFunctionList);
                        }
                    }

                    JSONArray pinParameters = pin.getJSONArray("pin_parameters");
                    if (pinParameters != null && !pinParameters.isEmpty()) {
                        List<ChipPinParameter> pinParameterList = new ArrayList<>();
                        for (int j = 0; j < pinParameters.size(); j++) {
                            JSONObject pinParameter = pinParameters.getJSONObject(j);
                            ChipPinParameter chipPinParameter = pinParameter.toJavaObject(ChipPinParameter.class);
                            chipPinParameter.setChipId(chipId);
                            chipPinParameter.setPinId(chipPin.getPinId());
                            pinParameterList.add(chipPinParameter);
                            List<Rule> ruleList = new ArrayList<>();
                            String parameterName = chipPinParameter.getParameterName() == null ? "" : chipPinParameter.getParameterName();
                            String dependenciesRuleName = String.format("引脚%s参数%s依赖规则", chipPin.getPinCode() == null ? "" : chipPin.getPinCode(),parameterName);
                            String symbol = chipPinParameter.getSymbol() == null ? "" : chipPinParameter.getSymbol();
                            Rule dependenciesRule = ruleService.createDependenciesRule(currentUser.getUserId(), relationalOperatorPattern, ruleToConditionListData, addConditionList, chipPinParameter.getDependencies(), parameterName, pinRuleSet,dependenciesRuleName,symbol);
                            String configurationRuleName = String.format("引脚%s参数%s配置规则", chipPin.getPinCode() == null ? "" : chipPin.getPinCode(),parameterName);
                            Rule configurationRule = ruleService.createConfigurationRule(currentUser.getUserId(), addConditionList, parameterConfigurationDataTypeList, ruleToConditionListData, chipPinParameter.getDataType(), chipPinParameter.getValidValues(), parameterName, pinRuleSet,configurationRuleName,symbol);
                            if(dependenciesRule != null){
                                dependenciesRule.setObjectId(chipPin.getPinId());
                                ruleList.add(dependenciesRule);
                                if(configurationRule != null){
                                    dependenciesRuleToConfigurationRuleData.put(dependenciesRule,configurationRule);
                                }
                            }
                            if(configurationRule != null){
                                configurationRule.setObjectId(chipPin.getPinId());
                                ruleList.add(configurationRule);
                            }
                            addRuleList.addAll(ruleList);
                        }
                        if (!pinParameterList.isEmpty()) {
                            //保存芯片引脚参数信息
                            chipPinParameterService.saveBatch(pinParameterList);
                        }
                    }
                }
            }
            JSONArray interfaceResources = chipData.getJSONArray("interface_resources");
            if (interfaceResources != null && !interfaceResources.isEmpty()) {
                for (int i = 0; i < interfaceResources.size(); i++) {
                    JSONObject interfaceResource = interfaceResources.getJSONObject(i);
                    ChipInterface chipInterface = interfaceResource.toJavaObject(ChipInterface.class);
                    chipInterface.setChipId(chipId);
                    //保存主控芯片接口信息
                    chipInterfaceService.save(chipInterface);
                    JSONArray resourcePins = interfaceResource.getJSONArray("resource_pins");
                    if (resourcePins != null && !resourcePins.isEmpty()) {
                        for (int j = 0; j < resourcePins.size(); j++) {
                            JSONObject resourcePin = resourcePins.getJSONObject(j);
                            ChipInterfacePinFunction chipInterfacePinFunction = new ChipInterfacePinFunction();
                            chipInterfacePinFunction.setInterfaceId(chipInterface.getInterfaceId());
                            chipInterfacePinFunction.setPinName(resourcePin.getString("pin_name"));
                            //保存芯片接口引脚功能信息
                            chipInterfacePinFunctionService.save(chipInterfacePinFunction);
                            JSONArray defaultPinParameters = resourcePin.getJSONArray("default_pin_parameters");
                            if (defaultPinParameters != null && !defaultPinParameters.isEmpty()) {
                                List<ChipInterfacePinFunctionParameter> pinFunctionParameterList = new ArrayList<>();
                                for (int k = 0; k < defaultPinParameters.size(); k++) {
                                    JSONObject defaultPinParameter = defaultPinParameters.getJSONObject(k);
                                    ChipInterfacePinFunctionParameter pinFunctionParameter = defaultPinParameter.toJavaObject(ChipInterfacePinFunctionParameter.class);
                                    pinFunctionParameter.setInterfacePinFunctionId(chipInterfacePinFunction.getInterfacePinFunctionId());
                                    pinFunctionParameterList.add(pinFunctionParameter);
                                }
                                if (!pinFunctionParameterList.isEmpty()) {
                                    //保存芯片接口引脚功能默认参数信息
                                    chipInterfacePinFunctionParameterService.saveBatch(pinFunctionParameterList);
                                }
                            }
                        }
                    }
                    JSONArray resourceParameters = interfaceResource.getJSONArray("resource_parameters");
                    if (resourceParameters != null && !resourceParameters.isEmpty()) {
                        List<ChipInterfaceParameter> interfaceParameterList = new ArrayList<>();
                        for (int j = 0; j < resourceParameters.size(); j++) {
                            JSONObject parameter = resourceParameters.getJSONObject(j);
                            ChipInterfaceParameter interfaceParameter = parameter.toJavaObject(ChipInterfaceParameter.class);
                            interfaceParameter.setInterfaceId(chipInterface.getInterfaceId());
                            interfaceParameterList.add(interfaceParameter);
                            List<Rule> ruleList = new ArrayList<>();
                            String parameterName = interfaceParameter.getParameterName() == null ? "" : interfaceParameter.getParameterName();
                            String dependenciesRuleName = String.format("接口资源%s参数%s依赖规则", chipInterface.getResourceName() == null ? "" : chipInterface.getResourceName(),parameterName);
                            String symbol = interfaceParameter.getSymbol() == null ? "" : interfaceParameter.getSymbol();
                            Rule dependenciesRule = ruleService.createDependenciesRule(currentUser.getUserId(), relationalOperatorPattern, ruleToConditionListData, addConditionList, interfaceParameter.getDependencies(), parameterName, interfaceResourceRuleSet,dependenciesRuleName,symbol);
                            String configurationRuleName = String.format("接口资源%s参数%s配置规则", chipInterface.getResourceName() == null ? "" : chipInterface.getResourceName(),parameterName);
                            Rule configurationRule = ruleService.createConfigurationRule(currentUser.getUserId(), addConditionList, parameterConfigurationDataTypeList, ruleToConditionListData, interfaceParameter.getDataType(), interfaceParameter.getValidValues(), parameterName, interfaceResourceRuleSet,configurationRuleName,symbol);
                            if(dependenciesRule != null){
                                dependenciesRule.setObjectId(chipInterface.getInterfaceId());
                                ruleList.add(dependenciesRule);
                                if(configurationRule != null){
                                    dependenciesRuleToConfigurationRuleData.put(dependenciesRule,configurationRule);
                                }
                            }
                            if(configurationRule != null){
                                configurationRule.setObjectId(chipInterface.getInterfaceId());
                                ruleList.add(configurationRule);
                            }
                            addRuleList.addAll(ruleList);
                        }
                        if (!interfaceParameterList.isEmpty()) {
                            //保存主控芯片接口参数信息
                            chipInterfaceParameterService.saveBatch(interfaceParameterList);
                        }
                    }
                }
            }
            ruleSetService.addParameterConfigurationRuleSet(ruleToConditionListData, dependenciesRuleToConfigurationRuleData, addRuleList, addConditionList);
        }
        return JsonUtil.getSuccess("");
    }




    /**
     * 删除主控芯片详细信息
     * @param chipId
     * @return
     */
    public void deleteMasterChipInfo(Integer chipId){
        List<ChipClockParameter> chipClockParameterList = chipClockParameterService.findByProperty(ChipClockParameter::getChipId,chipId);
        if (!chipClockParameterList.isEmpty()){
            //删除芯片时钟参数数据
            chipClockParameterService.removeByIds(chipClockParameterList.stream().map(ChipClockParameter::getClockParameterId).collect(Collectors.toList()));
        }
        List<ChipPinFunction> pinFunctionList = chipPinFunctionService.findByProperty(ChipPinFunction::getChipId,chipId);
        if (!pinFunctionList.isEmpty()){
            //删除引脚功能数据
            chipPinFunctionService.removeByIds(pinFunctionList.stream().map(ChipPinFunction::getPinFunctionId).collect(Collectors.toList()));
        }
        List<ChipPinParameter> pinParameterList = chipPinParameterService.findByProperty(ChipPinParameter::getChipId,chipId);
        if (!pinParameterList.isEmpty()){
            //删除引脚参数数据
            chipPinParameterService.removeByIds(pinParameterList.stream().map(ChipPinParameter::getPinParameterId).collect(Collectors.toList()));
        }
        List<ChipPin> pinList = chipPinService.findByProperty(ChipPin::getChipId,chipId);
        if (!pinList.isEmpty()){
            //删除引脚数据
            chipPinService.removeByIds(pinList.stream().map(ChipPin::getPinId).collect(Collectors.toList()));
        }
        List<ChipInterface> interfaceList = chipInterfaceService.findByProperty(ChipInterface::getChipId,chipId);
        if (!interfaceList.isEmpty()){
            //删除接口资源数据
            chipInterfaceService.removeByIds(interfaceList.stream().map(ChipInterface::getInterfaceId).collect(Collectors.toList()));
            List<Integer> interfaceIds = interfaceList.stream().map(ChipInterface::getInterfaceId).collect(Collectors.toList());
            List<ChipInterfaceParameter> interfaceParameterList = chipInterfaceParameterService.list(new QueryWrapper<ChipInterfaceParameter>().lambda().in(ChipInterfaceParameter::getInterfaceId,interfaceIds));
            if (!interfaceParameterList.isEmpty()){
                //删除接口资源参数数据
                chipInterfaceParameterService.removeByIds(interfaceParameterList.stream().map(ChipInterfaceParameter::getInterfaceParameterId).collect(Collectors.toList()));
            }
            List<ChipInterfacePinFunction> interfacePinFunctionList = chipInterfacePinFunctionService.list(new QueryWrapper<ChipInterfacePinFunction>().lambda().in(ChipInterfacePinFunction::getInterfaceId,interfaceIds));
            if (!interfacePinFunctionList.isEmpty()){
                //删除接口资源引脚功能数据
                chipInterfacePinFunctionService.removeByIds(interfacePinFunctionList.stream().map(ChipInterfacePinFunction::getInterfacePinFunctionId).collect(Collectors.toList()));
                List<Integer> interfacePinFunctionIds = interfacePinFunctionList.stream().map(ChipInterfacePinFunction::getInterfacePinFunctionId).collect(Collectors.toList());
                List<ChipInterfacePinFunctionParameter> interfacePinFunctionParameterList = chipInterfacePinFunctionParameterService.list(new QueryWrapper<ChipInterfacePinFunctionParameter>().lambda().in(ChipInterfacePinFunctionParameter::getInterfacePinFunctionId,interfacePinFunctionIds));
                if (!interfacePinFunctionParameterList.isEmpty()){
                    //删除接口资源引脚功能默认参数数据
                    chipInterfacePinFunctionParameterService.removeByIds(interfacePinFunctionParameterList.stream().map(ChipInterfacePinFunctionParameter::getId).collect(Collectors.toList()));
                }
            }
        }
        List<RuleSet> ruleSetList = ruleSetService.findByProperty(RuleSet::getChipId, chipId);
        List<Integer> ruleSetIdList = ruleSetList.stream().map(RuleSet::getRuleSetId).collect(Collectors.toList());
        ruleSetService.deleteByRuleSetIds(ruleSetIdList);
    }

    /**
     * 验证芯片json数据
     * @param jsonStr
     * @param chipType
     * @return
     */
    public JSONObject validateChipData(String jsonStr,Integer chipType){
        JSONObject chipData = null;
        if (StringUtils.isNotBlank(jsonStr)){
            try {
                chipData = JSONObject.parseObject(jsonStr);
                if (ChipTypeEnum.MASTER.getType().equals(chipType)){
                    JSONObject clocks = chipData.getJSONObject("clocks");
                    JSONArray pins = chipData.getJSONArray("pins");
                    JSONArray interfaceResources = chipData.getJSONArray("interface_resources");
                    if (clocks == null || pins == null || interfaceResources == null){
                        return null;
                    }
                }
            } catch (JSONException e) {
                return null;
            }
        }
        return chipData;
    }

    /**
     * 获取芯片列表
     * @return
     */
    public JSONObject getChipList(){
        JSONObject returnData = new JSONObject();
        JSONArray masterChipArray = new JSONArray();
        JSONArray slaveChipArray = new JSONArray();
        List<Chip> chipList = list();
        //主控芯片
        List<Chip> masterChipList = chipList.stream().filter(e ->ChipTypeEnum.MASTER.getType().equals(e.getType())).collect(Collectors.toList());
        Map<String,List<Chip>> groupMasterChipMap = masterChipList.stream().collect(Collectors.groupingBy(Chip::getDisplayCategory));
        groupMasterChipMap.forEach((key,value)-> masterChipArray.add(packageChipCategoryGroupData(key,value)));

        // 被控芯片
        List<Chip> slaveChipList = chipList.stream()
                .filter(e -> ChipTypeEnum.SLAVE.getType().equals(e.getType()))
                .collect(Collectors.toList());

        // 根据被控芯片ID查询驱动程序库，并组装芯片适配范围数据
        List<DriverLibrary> driverLibraryList = driverLibraryService.findAll();

        // 根据被控芯片ID分组
        Map<Integer, List<DriverLibrary>> groupDriverLibraryMap = driverLibraryList.stream()
                .collect(Collectors.groupingBy(DriverLibrary::getChipId));
        // 组装芯片适配范围数据
        slaveChipList.forEach(chip -> {
            int chipId = chip.getChipId();
            // 根据被控芯片ID查询驱动程序分组结果集
            List<DriverLibrary> driverLibraries = groupDriverLibraryMap.getOrDefault(chipId, Collections.emptyList());
            // Set去重
            Set<String> compatibleSet = driverLibraries.stream()
                    .flatMap(driverLibrary -> Arrays.stream(driverLibrary.getCompatible().split(",")))
                    .filter(StringUtils::isNotBlank)
                    .collect(Collectors.toSet());
            // 适配范围
            chip.setCompatible(StringUtils.join(compatibleSet, ","));
        });

        Map<String,List<Chip>> groupSlaveChipMap = slaveChipList.stream().collect(Collectors.groupingBy(Chip::getDisplayCategory));
        groupSlaveChipMap.forEach((key,value)-> slaveChipArray.add(packageChipCategoryGroupData(key,value)));
        returnData.put("masterChipArray",masterChipArray);
        returnData.put("slaveChipArray",slaveChipArray);
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,returnData);
    }

    /**
     * 组装芯片类别分组数据
     * @param key
     * @param chipList
     * @return
     */
    public JSONObject packageChipCategoryGroupData(String key,List<Chip> chipList){
        JSONObject categoryGroupData = new JSONObject();
        categoryGroupData.put("category",key);
        JSONArray chipArray = new JSONArray();
        for (Chip chip : chipList){
            JSONObject chipData = packageChipData(chip);
            chipArray.add(chipData);
        }
        categoryGroupData.put("chipArray",chipArray);
        return categoryGroupData;
    }

    /**
     * 组装芯片数据
     * @param chip
     * @return
     */
    public JSONObject packageChipData(Chip chip){
        JSONObject chipData = new JSONObject();
        chipData.put("chipId",chip.getChipId());
        chipData.put("type",chip.getType());
        chipData.put("model",chip.getModel());
        chipData.put("compatible",chip.getCompatible());
        chipData.put("category",chip.getCategory());
        chipData.put("displayName",chip.getDisplayName());
        chipData.put("displayCategory",chip.getDisplayCategory());
        chipData.put("manufacturer",chip.getManufacturer());
        chipData.put("description",chip.getDescription());
        chipData.put("overview",chip.getOverview());
        return chipData;
    }

    /**
     * 组装芯片时钟参数数据
     * @param clockParameter
     * @return
     */
    public JSONObject packageChipClockParameterData(ChipClockParameter clockParameter){
        JSONObject clockParameterData = new JSONObject();
        clockParameterData.put("clockParameterId",clockParameter.getClockParameterId());
        clockParameterData.put("parameterName",clockParameter.getParameterName());
        clockParameterData.put("dataType",clockParameter.getDataType());
        clockParameterData.put("validValues",clockParameter.getValidValues());
        clockParameterData.put("defaultValue",clockParameter.getDefaultValue());
        clockParameterData.put("symbol",clockParameter.getSymbol());
        clockParameterData.put("dependencies",clockParameter.getDependencies());
        return clockParameterData;
    }

    /**
     * 获取芯片类别
     * @return
     */
    public List<String> getChipCategoryList(Integer chipType){
        LambdaQueryWrapper<Chip> categoryQueryWrapper = new LambdaQueryWrapper<Chip>()
                .select(Chip::getDisplayCategory)
                .eq(Chip::getType,chipType)
                .eq(Chip::getIsDelete,IsNotEnum.NOT.getId())
                .groupBy(Chip::getDisplayCategory);
        List<Map<String,Object>> list = listMaps(categoryQueryWrapper);
        List<String> dynamicCategoryList = list.stream().filter(m ->StringUtils.isNotBlank(m.get("display_category").toString())).map(m ->m.get("display_category").toString()).collect(Collectors.toList());
        return dynamicCategoryList;
    }

    /**
     * 获取芯片类别列表
     * @return
     */
    public JSONObject loadChipCategoryList(){
        JSONObject resultData = new JSONObject();
        List<String> masterCategoryList = getChipCategoryList(ChipTypeEnum.MASTER.getType());
        List<String> slaveCategoryList = getChipCategoryList(ChipTypeEnum.SLAVE.getType());
        List<String> fixedMasterCategoryList = Arrays.stream(MasterChipCategoryEnum.values()).map(MasterChipCategoryEnum::getCategory).collect(Collectors.toList());
        List<String> fixedSlaveCategoryList = Arrays.stream(SlaveChipCategoryEnum.values()).map(SlaveChipCategoryEnum::getCategory).collect(Collectors.toList());
        resultData.fluentPut("masterChipCategory",masterCategoryList).fluentPut("slaveChipCategory",slaveCategoryList).
                fluentPut("fixedMasterChipCategory",fixedMasterCategoryList).fluentPut("fixedSlaveChipCategory",fixedSlaveCategoryList);
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,resultData);
    }

    /**
     * 根据芯片类别加载芯片树
     * @return
     */
    public JSONArray loadTreeByCategory(Integer chipType){
        List<String> categoryList;
        if (ChipTypeEnum.MASTER.getType().equals(chipType)){
            categoryList = getChipCategoryList(chipType);
        }else{
            categoryList = getChipCategoryList(chipType);
        }
        List<Chip> chipList = findByProperty(Chip::getType,chipType);
        JSONArray jsonArray = new JSONArray();
        for (String category : categoryList){
            JSONObject categoryData = new JSONObject();
            categoryData.put("label",category);
            categoryData.put("value",category);
            JSONArray children = new JSONArray();
            List<Chip> categoryChipList = chipList.stream().filter(e ->e.getDisplayCategory().equals(category)).collect(Collectors.toList());
            for (Chip chip : categoryChipList){
                JSONObject chipData = new JSONObject();
                chipData.put("label",chip.getDisplayName());
                chipData.put("value",chip.getChipId());
                children.add(chipData);
            }
            categoryData.put("children",children);
            jsonArray.add(categoryData);
        }
        return jsonArray;
    }

    /**
     * 获取芯片列表
     * @param pageParam
     * @return
     */
    public JSONObject loadGrid(PageParam pageParam){
        JSONObject resultData = new JSONObject();

        Map<String, Object> params = pageParam.getParams();
        int currentPage = pageParam.getCurrentPage();
        int pageSize = pageParam.getPageSize();
        Map<String,Object> sortFields= pageParam.getSort();
        if(sortFields.isEmpty()){
            sortFields.put("chipId",APP.DESC);
        }
        QueryWrapper<Chip> chipQueryWrapper = getFormSearchWrapper(params, new String[]{"displayName","model"}, new String[]{"type","displayCategory"}, sortFields, null);
        IPage<Chip> page = findPageVue(currentPage,pageSize,chipQueryWrapper);
        List<Chip> chipList = page.getRecords();
        JSONArray chipArray = new JSONArray();
        for (Chip chip : chipList){
            JSONObject chipData = packageChipData(chip);
            chipArray.add(chipData);
        }
        resultData.put(APP.DATA, chipArray);
        resultData.put(APP.TOTAL_COUNT, page.getTotal());
        resultData.put(APP.CURRENT_PAGE, page.getCurrent());
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,resultData);
    }

    /**
     * 加载单个芯片信息
     * @param query
     * @return
     */
    public JSONObject getChipInfo(JSONObject query){
        JSONObject chipData = new JSONObject();
        Integer chipId = query.getInteger("chipId");
        if (chipId != null){
            Chip chip = findById(chipId);
            if (chip != null){
                List<Files> filesList = filesService.getFileList(Arrays.asList(FileRelationTypeEnum.CHIP_DEFINITION.getRelationTypeId(),FileRelationTypeEnum.CHIP_CLOCK_PARAMETER.getRelationTypeId(),FileRelationTypeEnum.CHIP_PIN.getRelationTypeId(),FileRelationTypeEnum.CHIP_PERFORMANCE_PARAMETER.getRelationTypeId()),chipId);
                if (ChipTypeEnum.MASTER.getType().equals(chip.getType())){
                    List<ChipClockParameter> chipClockParameterList = chipClockParameterService.getListByChipIds(Arrays.asList(chipId));
                    JSONArray clockParameters = new JSONArray();
                    for (ChipClockParameter clockParameter : chipClockParameterList){
                        JSONObject clockParameterData = packageChipClockParameterData(clockParameter);
                        clockParameters.add(clockParameterData);
                    }
                    chipData.put("clockParameters",clockParameters);
                    List<Files> clockParameterFiles = filesList.stream().filter(e ->e.getRelationId().equals(chip.getChipId()) && e.getRelationTypeId().equals(FileRelationTypeEnum.CHIP_CLOCK_PARAMETER.getRelationTypeId())).collect(Collectors.toList());
                    chipData.put("clockParameterFiles",clockParameterFiles);
                    chipData.put("clockParameterFilesBase64",clockParameterFiles.isEmpty() ? "" : FileUtils.fileToBase64(baseFilePath + clockParameterFiles.get(0).getPath().replaceFirst("uploads/", "")));
                }
                if (ChipTypeEnum.SLAVE.getType().equals(chip.getType())){
                    List<Files> performanceParameterFiles = filesList.stream().filter(e ->e.getRelationId().equals(chip.getChipId()) && e.getRelationTypeId().equals(FileRelationTypeEnum.CHIP_PERFORMANCE_PARAMETER.getRelationTypeId())).collect(Collectors.toList());
                    chipData.put("performanceParameterFiles",performanceParameterFiles);
                    chipData.put("performanceParameterFilesBase64",performanceParameterFiles.isEmpty() ? "" : FileUtils.fileToBase64(baseFilePath + performanceParameterFiles.get(0).getPath().replaceFirst("uploads/", "")));
                }
                List<Files> pinFiles = filesList.stream().filter(e ->e.getRelationId().equals(chip.getChipId()) && e.getRelationTypeId().equals(FileRelationTypeEnum.CHIP_PIN.getRelationTypeId())).collect(Collectors.toList());
                chipData.put("pinFiles",pinFiles);
                chipData.put("pinFilesBase64",pinFiles.isEmpty() ? "" : FileUtils.fileToBase64(baseFilePath + pinFiles.get(0).getPath().replaceFirst("uploads/", "")));
                List<Files> chipDefinitionFiles = filesList.stream().filter(e ->e.getRelationId().equals(chip.getChipId()) && e.getRelationTypeId().equals(FileRelationTypeEnum.CHIP_DEFINITION.getRelationTypeId())).collect(Collectors.toList());
                chipData.put("chipDefinitionFiles",chipDefinitionFiles);
                List<CircuitGenerationModuleChip> circuitGenerationModuleChipList = chipId == null ? new ArrayList<>() : circuitGenerationModuleChipService.findByProperty(CircuitGenerationModuleChip::getChipId, chipId);
                chipData.put("circuitGenerationModuleChipList",circuitGenerationModuleChipList);
            }
        }
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,chipData);
    }


    /**
     * 修改芯片
     * @param data
     * @param currentUser
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject update(JSONObject data,Users currentUser){
        Integer chipId = data.getInteger("chipId");
        Chip oldChip = findById(chipId);
        if (oldChip == null){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的芯片数据!");
        }
        JSONArray mappingArray = data.getJSONArray("mapping");
        Boolean processMappingResult = circuitGenerationModuleChipService.processMappingArray(mappingArray,chipId);
        Chip newChip = data.toJavaObject(Chip.class);
        if (isDuplicateModelBySameManufacturer(newChip.getManufacturer(),newChip.getModel(),chipId)){
            return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"相同厂商下,芯片型号已存在!");
        }
        newChip.setUpdateUserId(currentUser.getUserId());
        updateById(newChip);
        updateChipFiles(data,chipId,oldChip.getType(),currentUser.getUserId());

        Files chipDefinitionFile = filesService.getFileList(FileRelationTypeEnum.CHIP_DEFINITION.getRelationTypeId(),chipId).get(0);
        String oldPath = baseFilePath + chipDefinitionFile.getPath().replaceFirst("uploads/", "");
        String jsonStr = FileUtils.getStr(oldPath);
        JSONObject chipData = JSON.parseObject(jsonStr, Feature.OrderedField);
        putChipInfo(chipData,newChip);
        if (ChipTypeEnum.MASTER.getType().equals(oldChip.getType())){
            List<ChipClockParameter> oldChipClockParameterList = chipClockParameterService.findByProperty(ChipClockParameter::getChipId,chipId);
            if (!oldChipClockParameterList.isEmpty()){
                //删除芯片时钟参数数据
                chipClockParameterService.removeByIds(oldChipClockParameterList.stream().map(ChipClockParameter::getClockParameterId).collect(Collectors.toList()));
            }
            List<ChipClockParameter> newChipClockParameterList = data.getJSONArray("clockParameters").toJavaList(ChipClockParameter.class);
            newChipClockParameterList.forEach(e ->e.setChipId(chipId));
            chipClockParameterService.saveBatch(newChipClockParameterList);
            handleClockConfigurationRuleSet(currentUser, chipId, newChipClockParameterList);
            putChipClockParameters(chipData,newChipClockParameterList);
        }
        String newPath = filesService.createJsonFile(chipData);
        if (StringUtils.isNotBlank(newPath)){
            newPath = newPath.replaceFirst(baseFilePath, "uploads/");
            chipDefinitionFile.setPath(newPath);
            filesService.updateById(chipDefinitionFile);
            filesService.deleteFile(oldPath);
        }
        if (processMappingResult){
            return JsonUtil.getSuccess("");
        }else{
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"芯片映射数据更新失败!");
        }
    }

    /**
     * 处理时钟配置规则集
     * @param currentUser
     * @param chipId
     * @param newChipClockParameterList
     */
    public void handleClockConfigurationRuleSet(Users currentUser, Integer chipId, List<ChipClockParameter> newChipClockParameterList) {
        Map<SFunction<RuleSet, ?>, Object> ruleSetFieldValueMap = new HashMap<>();
        ruleSetFieldValueMap.put(RuleSet::getChipId,chipId);
        ruleSetFieldValueMap.put(RuleSet::getType, RuleSetTypeEnum.CLOCK_CONFIGURATION.getId());
        List<RuleSet> ruleSetList = ruleSetService.findByProperties(ruleSetFieldValueMap);
        RuleSet clockRuleSet;
        if(ruleSetList.isEmpty()){
            clockRuleSet = ruleSetService.createParameterConfigurationRuleSet(currentUser.getUserId(), "时钟配置", chipId);
            ruleSetService.save(clockRuleSet);
        }
        clockRuleSet = ruleSetList.get(0);
        List<Integer> ruleSetIdList = ruleSetList.stream().map(RuleSet::getRuleSetId).collect(Collectors.toList());
        ruleService.removeByRuleSetIdList(ruleSetIdList);
        conditionService.removeByRuleSetIdList(ruleSetIdList);
        Pattern relationalOperatorPattern = conditionService.getRelationalOperatorPattern();
        Map<Rule,List<Condition>> ruleToConditionListData = new HashMap<>();
        Map<Rule,Rule> dependenciesRuleToConfigurationRuleData = new HashMap<>();
        List<Rule> addRuleList = new ArrayList<>();
        List<Condition> addConditionList = new ArrayList<>();
        List<String> parameterConfigurationDataTypeList = ParameterConfigurationDataTypeEnum.getTypeList();
        for(ChipClockParameter chipClockParameter : newChipClockParameterList){
            List<Rule> ruleList = new ArrayList<>();
            String parameterName = chipClockParameter.getParameterName() == null ? "" : chipClockParameter.getParameterName();
            String symbol = chipClockParameter.getSymbol() == null ? "" : chipClockParameter.getSymbol();
            Rule dependenciesRule = ruleService.createDependenciesRule(currentUser.getUserId(), relationalOperatorPattern, ruleToConditionListData, addConditionList, chipClockParameter.getDependencies(), parameterName, clockRuleSet,null,symbol);
            Rule configurationRule = ruleService.createConfigurationRule(currentUser.getUserId(), addConditionList, parameterConfigurationDataTypeList, ruleToConditionListData, chipClockParameter.getDataType(), chipClockParameter.getValidValues(), parameterName, clockRuleSet,null,symbol);
            if(dependenciesRule != null){
                ruleList.add(dependenciesRule);
                if(configurationRule != null){
                    dependenciesRuleToConfigurationRuleData.put(dependenciesRule,configurationRule);
                }
            }
            if(configurationRule != null){
                ruleList.add(configurationRule);
            }
            addRuleList.addAll(ruleList);
        }
        ruleSetService.addParameterConfigurationRuleSet(ruleToConditionListData, dependenciesRuleToConfigurationRuleData, addRuleList, addConditionList);
    }

    /**
     * 修改芯片基本信息
     * @param chipData
     * @param chip
     */
    public void putChipInfo(JSONObject chipData,Chip chip){
        chipData.put("model",chip.getModel());
        chipData.put("category",chip.getCategory());
        chipData.put("manufacturer",chip.getManufacturer());
        chipData.put("display_name",chip.getDisplayName());
        chipData.put("display_category",chip.getDisplayCategory());
        chipData.put("description",chip.getDescription());
        chipData.put("overview",chip.getOverview());
    }

    /**
     * 修改芯片时钟参数信息
     * @param chipData
     * @param chipClockParameterList
     */
    public void putChipClockParameters(JSONObject chipData,List<ChipClockParameter> chipClockParameterList){
        JSONArray clockParameters = new JSONArray();
        for (ChipClockParameter clockParameter : chipClockParameterList){
            Map<String,Object> parameterData = new LinkedHashMap();
            parameterData.put("parameter_name",clockParameter.getParameterName());
            parameterData.put("symbol",clockParameter.getSymbol());
            parameterData.put("dependencies",clockParameter.getDependencies());
            String dataType = clockParameter.getDataType();
            parameterData.put("data_type",dataType);
            parameterData.put("valid_values",clockParameter.getValidValues());
            String defaultValue = clockParameter.getDefaultValue();
            if (defaultValue != null){
                if ("integer".equals(dataType)){
                    parameterData.put("default_value",Integer.parseInt(defaultValue));
                }else if ("float".equals(dataType)){
                    parameterData.put("default_value",Float.parseFloat(defaultValue));
                }else if ("boolean".equals(dataType)){
                    parameterData.put("default_value",Boolean.parseBoolean(defaultValue));
                }else {
                    parameterData.put("default_value",defaultValue);
                }
            }
            clockParameters.add(parameterData);
        }
        chipData.getJSONObject("clocks").put("parameters",clockParameters);
    }



    /**
     * 删除芯片
     * @param data
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject delete(JSONObject data){
        Integer chipId = data.getInteger("chipId");
        Chip chip = findById(chipId);
        if (chip != null){
            List<DriverLibrary> driverLibraryList = driverLibraryService.findByProperty(DriverLibrary::getChipId,chipId);
            if (!driverLibraryList.isEmpty()){
                return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_DENY,"存在关联的驱动库数据,请勿删除!");
            }
            if (ChipTypeEnum.MASTER.getType().equals(chip.getType())){
                deleteMasterChipInfo(chipId);
            }
            deleteFiles(chipId,chip.getType());
            removeById(chipId);
        }
        LambdaQueryWrapper<CircuitGenerationModuleChip> circuitGenerationModuleChipQueryWrapper = new LambdaQueryWrapper<>();
        circuitGenerationModuleChipQueryWrapper.eq(CircuitGenerationModuleChip::getChipId,chipId);
        List<CircuitGenerationModuleChip> circuitGenerationModuleChipList = circuitGenerationModuleChipService.list(circuitGenerationModuleChipQueryWrapper);
        boolean removeResult = true;
        if (!circuitGenerationModuleChipList.isEmpty()){
           removeResult = circuitGenerationModuleChipService.removeByIds(circuitGenerationModuleChipList.stream().map(CircuitGenerationModuleChip::getId).collect(Collectors.toList()));
        }
        if (removeResult){
            return JsonUtil.getSuccess("");
        }else{
            return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_FAIL,"电路生成模块芯片表芯片信息删除失败!");
        }
    }

    /**
     * 判断相同厂商下,芯片型号是否重复
     * @param manufacturer
     * @param model
     * @param chipId
     * @return
     */
    public Boolean isDuplicateModelBySameManufacturer(String manufacturer,String model,Integer chipId){
        QueryWrapper<Chip> chipQueryWrapper = new QueryWrapper<>();
        chipQueryWrapper.lambda().eq(Chip::getManufacturer,manufacturer);
        chipQueryWrapper.lambda().eq(Chip::getModel,model);
        if (chipId != null){
            chipQueryWrapper.lambda().ne(Chip::getChipId,chipId);
        }
        int count = count(chipQueryWrapper);
        if (count > 0){
            return true;
        }
        return false;
    }

    /**
     * 文件规则检查
     * @param webData
     * @return
     */
    public JSONObject fileRuleCheck(JSONObject webData){
        String filePath = webData.getString("filePath");
        Integer ruleSetType = webData.getInteger("ruleSetType");
        JSONObject analysisFileJson = analysisFile(filePath);
        if(!analysisFileJson.getBoolean(APP.SUCCESS)){
            return analysisFileJson;
        }
        JSONObject originData = analysisFileJson.getJSONObject(APP.DATA);
        List<RuleSet> ruleSetList = ruleSetService.findByProperty(RuleSet::getType, ruleSetType);
        if(ruleSetList.isEmpty()){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"找不到对应的规则集");
        }
        if(ruleSetList.size() > 1){
            return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,"存在多个规则集，请检查");
        }
        RuleSet ruleSet = ruleSetList.get(0);
        List<Rule> ruleList = ruleService.findByProperty(Rule::getRuleSetId,ruleSet.getRuleSetId());
        List<Condition> conditionList = conditionService.findByProperty(Condition::getRuleSetId,ruleSet.getRuleSetId());
        List<JSONObject> notPassDataList = new ArrayList<>();
        JSONObject ruleIdToRuleJudgeResultData = new JSONObject();
        List<Rule> executedRuleList = new ArrayList<>();
        for(Rule rule : ruleList){
            executeRule(conditionList,rule,ruleSet,notPassDataList,ruleList,executedRuleList,ruleIdToRuleJudgeResultData,originData);
        }
        JSONObject data = new JSONObject();
        data.fluentPut("notPassDataList",notPassDataList);
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,data);
    }

    /**
     * 执行规则
     * @param conditionList 条件列表
     * @param rule 规则
     * @param ruleSet 规则集
     * @param notPassDataList 未通过数据列表
     * @param ruleList 规则列表
     * @param executedRuleList 执行过的规则列表
     * @param ruleIdToRuleJudgeResultData 规则id对应规则判断结果数据
     * @param originData 源数据
     */
    public Boolean executeRule(List<Condition> conditionList,Rule rule,RuleSet ruleSet,List<JSONObject> notPassDataList,List<Rule> ruleList,List<Rule> executedRuleList,JSONObject ruleIdToRuleJudgeResultData,JSONObject originData){
        List<Integer> executedRuleIdList = executedRuleList.stream().map(Rule::getRuleId).collect(Collectors.toList());
        if(executedRuleIdList.contains(rule.getRuleId())){
            return ruleIdToRuleJudgeResultData.getBoolean(rule.getRuleId().toString());
        }
        if(rule.getPrepositionRuleId() != null){
            Rule prepositionRule = ruleList.stream().filter(r -> r.getRuleId().equals(rule.getPrepositionRuleId())).findFirst().orElse(null);
            if(prepositionRule != null){
                Boolean executeRuleResult = executeRule(conditionList, prepositionRule, ruleSet, notPassDataList, ruleList, executedRuleList,ruleIdToRuleJudgeResultData, originData);
                if(executeRuleResult != null && !executeRuleResult){
                    JSONObject notPassData = new JSONObject();
                    notPassData.fluentPut("outputInfo",String.format("前置规则<%s>未通过,规则未执行",prepositionRule.getRuleName() == null ? "/" : prepositionRule.getRuleName(),rule.getRuleName() == null ? "/" : rule.getRuleName()));
                    packageNotPassData(notPassData,rule,ruleSet,originData);
                    notPassDataList.add(notPassData);
                    return null;
                }
            }
        }
        List<Condition> conditionListByRuleId = conditionList.stream().filter(c -> rule.getRuleId().equals(c.getRuleId())).collect(Collectors.toList());
        List<Boolean> conditionJudgeResultList = new ArrayList<>();
        for(Condition condition : conditionListByRuleId){
            JSONObject evaluateJson = null;
            try {
                evaluateJson = conditionHandleService.evaluate(condition.getFactMode(), condition.getComparator(), condition.getStandardSpecification(), originData);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if(evaluateJson == null || !evaluateJson.getBoolean(APP.SUCCESS)){
                    String errorInfo = "";
                    if(evaluateJson == null){
                        errorInfo = "异常信息：未知异常";
                        conditionJudgeResultList.add(false);
                    }else{
                        if(!evaluateJson.getBoolean(APP.SUCCESS)){
                            errorInfo = evaluateJson.getString(APP.MESSAGE);
                        }
                        conditionJudgeResultList.add(evaluateJson.getBoolean(APP.SUCCESS));
                    }
                    JSONObject notPassData = new JSONObject();
                    notPassData.fluentPut("outputInfo",String.format("不满足规则<%s>中<%d>条件,%s",rule.getRuleName() == null ? "/" : rule.getRuleName(),condition.getOrderId(),errorInfo));
                    packageNotPassData(notPassData,rule,ruleSet,originData);
                    notPassData.fluentPut("conditionId",condition.getConditionId());
                    notPassDataList.add(notPassData);
                }
            }
        }
        boolean ruleJudgeResult;
        if(ConditionalRelationEnum.OR.getId().equals(rule.getConditionalRelation())){
            ruleJudgeResult = conditionJudgeResultList.contains(true);
        }else{
            // 目前只有并且和或者，或者之外(并且和空:认为所有条件都要满足)
            ruleJudgeResult = !conditionJudgeResultList.contains(false);
        }
        executedRuleList.add(rule);
        ruleIdToRuleJudgeResultData.fluentPut(rule.getRuleId().toString(),ruleJudgeResult);
        return ruleJudgeResult;
    }

    /**
     * 组装不通过数据
     * @param notPassData
     * @param rule
     * @param ruleSet
     * @param originData
     */
    public void packageNotPassData(JSONObject notPassData,Rule rule,RuleSet ruleSet,JSONObject originData){
        notPassData.fluentPut("ruleSetId",ruleSet.getRuleSetId())
                .fluentPut("ruleSetName",ruleSet.getRuleSetName() == null ? "" :ruleSet.getRuleSetName())
                .fluentPut("ruleName",rule.getRuleName() == null ? "" : rule.getRuleName())
                .fluentPut("ruleId",rule.getRuleId());
    }



    /**
     * 解析文件
     * @param filePath
     * @return
     */
    public JSONObject analysisFile(String filePath){
        if(StringUtils.isBlank(filePath)){
            return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"文件路径为空，请检查");
        }
        JSONObject originData;
        try {
            byte[] bytes = java.nio.file.Files.readAllBytes(Paths.get(baseFilePath + filePath.substring(filePath.indexOf("/"))));
            String content = new String(bytes, StandardCharsets.UTF_8);
            originData = JSONObject.parseObject(content);
        } catch (Exception e) {
            e.printStackTrace();
            return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"文件解析有误，请检查传入的文件格式是否有误或联系管理员");
        }
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,originData);
    }

    /**
     * 加载树
     * @return
     */
    public JSONObject loadTree(){
        List<Chip> chipList = findAll();
        ChipTypeEnum[] chipTypeEnums = ChipTypeEnum.values();
        List<JSONObject> dataList = new ArrayList<>();
        List<String> masterCategoryList = getChipCategoryList(ChipTypeEnum.MASTER.getType());
        List<String> slaveCategoryList = getChipCategoryList(ChipTypeEnum.SLAVE.getType());
        for(ChipTypeEnum chipTypeEnum : chipTypeEnums){
            JSONObject chipTypeData = new JSONObject();
            chipTypeData.fluentPut("label",chipTypeEnum.getDescription())
                    .fluentPut("value",chipTypeEnum.getDescription());
            List<Chip> chipListByType = chipList.stream().filter(c -> chipTypeEnum.getType().equals(c.getType())).collect(Collectors.toList());
            List<JSONObject> categoryDataList = new ArrayList<>();
            if(ChipTypeEnum.MASTER.getType().equals(chipTypeEnum.getType())){
                for(String masterCategory : masterCategoryList){
                    packageTreeCategoryDataList(chipListByType,masterCategory,categoryDataList);
                }
            }
            if(ChipTypeEnum.SLAVE.getType().equals(chipTypeEnum.getType())){
                for(String slaveCategory : slaveCategoryList){
                    packageTreeCategoryDataList(chipListByType,slaveCategory,categoryDataList);
                }
            }
            chipTypeData.fluentPut("children",categoryDataList);
            dataList.add(chipTypeData);
        }
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,dataList);
    }

    /**
     * 组装树品类数据列表
     * @param chipListByType
     * @param category
     * @param categoryDataList
     */
    public void packageTreeCategoryDataList(List<Chip> chipListByType, String category, List<JSONObject> categoryDataList){
        JSONObject categoryData = new JSONObject();
        List<Chip> chipListByCategory = chipListByType.stream().filter(c -> category.equals(c.getDisplayCategory())).collect(Collectors.toList());
        List<JSONObject> chipDataList = new ArrayList<>();
        for(Chip chip : chipListByCategory){
            JSONObject chipData = new JSONObject();
            chipData.fluentPut("label",chip.getDisplayName() == null ? "" : chip.getDisplayName())
                    .fluentPut("value",chip.getChipId())
                    .fluentPut("type",chip.getType());
            chipDataList.add(chipData);
        }
        categoryData.fluentPut("label",category)
                .fluentPut("value",category)
                .fluentPut("children",chipDataList);
        categoryDataList.add(categoryData);
    }



}
